package com.guyu.app.common.util;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.guyu.app.common.enums.TelecomEnum;

import java.util.List;

/**
 * <p> 运营商解析 </p>
 * ICCID编码规则
 * <p>
 * 中国移动
 * 89860 NMF SS YYGXXXXXX P
 * 89： 行业，89代表电信行业
 * 86： 国家，86代表中国
 * 00： 发卡方，00/02/04/07代表中国移动，01/06/09代表中国联通，03/11代表中国电信
 * M： 号段，对应用户号码前3位 【0-159,1-158,2-150,3-151,4-134,5-135,6-136,7-137,8-138,9-139,A-157,B-188,C-152,D-147,E-187,F-182】
 * F： 用户号码第4位
 * SS： 省编号
 * YY： 编制ICCID时年号的后两位
 * G： SIM卡供应商代码
 * X…X： 用户识别码
 * P： 校验位
 * <p>
 * 中国联通
 * 898601YY8SSXXXXXXXXP
 * 89： 国际编号
 * 86： 国家编号，86：中国
 * 01： 运营商编号，01：中国联通
 * YY： 编制ICCID时年号的后两位
 * 8： 中国联通ICCID默认此位为8
 * SS：2位省份编码
 * X…X： 卡商生产的顺序编码
 * P： 校验位
 * <p>
 * 中国电信
 * 898603YYXMHHHXXXXXXP
 * 89：国际编号
 * 86：国家编号，86：中国
 * 03：运营商编号，03：中国电信
 * YY：编制ICCID时的年号（取后两位）
 * M ：保留位，固定为0
 * HHH：本地网地区代码，位数不够前补零。
 * XXXXXXP：7位流水号，建议前2位作为批次号
 *
 * @author tanyp
 * @link https://zhuanlan.zhihu.com/p/48113848?utm_id=0
 * @date 2023/9/19
 */
public class TelecomUtil {
    //移动
    public static final List<String> IMSI_CHINA_MOBILE = Lists.newArrayList("46000", "46002", "46004", "46007");
    //联通
    public static final List<String> IMSI_CHINA_UNICOM = Lists.newArrayList("46001", "46006", "46009");
    //电信
    public static final List<String> IMSI_CHINA_TELECOM = Lists.newArrayList("46003", "46005", "46011");
    //广电
    public static final List<String> IMSI_CHINA_BROADNET = Lists.newArrayList("46015");

    //移动
    public static final List<String> ICCID_CHINA_MOBILE = Lists.newArrayList("898600", "898602", "898604", "898607");
    //联通
    public static final List<String> ICCID_CHINA_UNICOM = Lists.newArrayList("898601", "898606", "898609");
    //电信
    public static final List<String> ICCID_CHINA_TELECOM = Lists.newArrayList("898603", "898611");
    //广电
    public static final List<String> ICCID_CHINA_BROADNET = Lists.newArrayList("898615");
    //国家编号
    public static final List<String> COUNTRY_CODE_NUMBER = Lists.newArrayList("+86", "86");

    /**
     * 根据IMSI解析运营商
     */
    public static TelecomEnum getIspByImsi(String imsi) {
        if (StrUtil.isBlank(imsi)) {
            return TelecomEnum.UNKNOWN;
        }
        for (String prefix : IMSI_CHINA_MOBILE) {
            if (StrUtil.startWith(imsi, prefix)) {
                return TelecomEnum.CHINA_MOBILE;
            }
        }
        for (String prefix : IMSI_CHINA_UNICOM) {
            if (StrUtil.startWith(imsi, prefix)) {
                return TelecomEnum.CHINA_UNICOM;
            }
        }
        for (String prefix : IMSI_CHINA_TELECOM) {
            if (StrUtil.startWith(imsi, prefix)) {
                return TelecomEnum.CHINA_TELECOM;
            }
        }
        for (String prefix : IMSI_CHINA_BROADNET) {
            if (StrUtil.startWith(imsi, prefix)) {
                return TelecomEnum.CHINA_BROADNET;
            }
        }
        return TelecomEnum.UNKNOWN;
    }

    /**
     * 根据ICCID解析运营商
     */
    public static TelecomEnum getIspByIccid(String iccid) {
        if (StrUtil.isBlank(iccid)) {
            return TelecomEnum.UNKNOWN;
        }
        for (String prefix : ICCID_CHINA_MOBILE) {
            if (StrUtil.startWith(iccid, prefix)) {
                return TelecomEnum.CHINA_MOBILE;
            }
        }
        for (String prefix : ICCID_CHINA_UNICOM) {
            if (StrUtil.startWith(iccid, prefix)) {
                return TelecomEnum.CHINA_UNICOM;
            }
        }
        for (String prefix : ICCID_CHINA_TELECOM) {
            if (StrUtil.startWith(iccid, prefix)) {
                return TelecomEnum.CHINA_TELECOM;
            }
        }
        for (String prefix : ICCID_CHINA_BROADNET) {
            if (StrUtil.startWith(iccid, prefix)) {
                return TelecomEnum.CHINA_BROADNET;
            }
        }
        return TelecomEnum.UNKNOWN;
    }

    /**
     * 去除国家编号
     */
    public static String removeGSB(String phone) {
        for (String gsb : COUNTRY_CODE_NUMBER) {
            if (StrUtil.startWith(phone, gsb)) {
                return StrUtil.sub(phone, gsb.length(), phone.length());
            }
        }
        return phone;
    }
}
